/*
 * @文件描述: 
 * @版本: 
 * @作者: 周晨阳
 * @Date: 2021-02-03 17:36:08
 */
#include "beeper.h"
#ifndef WIN_SIM

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define INFO_DURATION 2
#define ERROR_DURATION 100
#define WARN_DURATION 80

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
static uint8_t State = BEEPER_UNMUTE;
static rt_timer_t timer;
static rt_timer_t repeatTimer;
static rt_tick_t beepTime = 100;
static rt_tick_t repeatInterval = 100;
static uint8_t repeatTimes = 1;
static uint8_t beeperState = 0;
/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/
static void beep(void *p)
{
    GPIO_ResetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
    beeperState = 0;
    //printf("beep done\n");
}
static void repeat(void *p)
{
    static uint8_t repeatTimesTmp = 0;
    repeatTimesTmp++;
    if (repeatTimesTmp <= repeatTimes * 2)
    {
        if (beeperState == 1)
        {
            GPIO_ResetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
            beeperState = 0;
        }
        else
        {
            GPIO_SetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
            beeperState = 1;
        }
    }
    else
    {
        rt_timer_stop(repeatTimer);
        repeatTimesTmp = 0;
        GPIO_ResetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
        beeperState = 0;
    }
}
void Beeper_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(BEEPER_GPIO_CLK, ENABLE); //使能

    GPIO_InitStructure.GPIO_Pin = BEEPER_GPIO_PIN;    //
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //普通输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;    //下拉
    GPIO_Init(BEEPER_GPIO_PORT, &GPIO_InitStructure); //初始化GPIO

    GPIO_ResetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
    timer = rt_timer_create("beep",
                            beep,
                            NULL,
                            beepTime,
                            RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT);
    repeatTimer = rt_timer_create("repeat",
                                  repeat,
                                  NULL,
                                  repeatInterval,
                                  RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_PERIODIC);
#ifndef MUTE
    beeperTrigger(10);
#endif // !MUTE
    printf("beeper init done...\n");
}
/**
 * @brief : 静音
 * @param {*}
 * @return {*}
 */
void beeperMute(void)
{
    State = BEEPER_MUTE;
}
/**
 * @brief : 解除静音
 * @param {*}
 * @return {*}
 */
void beeperUnMute(void)
{
    State = BEEPER_UNMUTE;
}

/**
 * @brief : 低级蜂鸣器控制函数
 * @param {*}
 * @return {*}
 */
static void trigger(uint16_t ms)
{
    if (beeperState == 1)
    {
        return;
    }
    beepTime = ms;
    rt_timer_control(timer, RT_TIMER_CTRL_SET_TIME, &beepTime);
    //rt_timer_stop(timer);
    if (rt_timer_start(timer) == RT_EOK)
    {
        beeperState = 1;
        GPIO_SetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
    }
}
/**
 * @brief : 
 * @param {*}
 * @return {*}
 */
static void repeatBeep(uint8_t ms)
{
    repeatInterval = ms;
    rt_timer_control(repeatTimer, RT_TIMER_CTRL_SET_TIME, &repeatInterval);

    if (rt_timer_start(repeatTimer) == RT_EOK)
    {
        beeperState = 1;
        GPIO_SetBits(BEEPER_GPIO_PORT, BEEPER_GPIO_PIN);
    }
}
/**
 * @brief : 带预定义类型的单次触发蜂鸣器
 * @param {int} ms 响的时长 ,也可以是预定义的一些提示音类型
 * @return {*}
 */
void beeperTrigger(int ms)
{

    if (State != BEEPER_UNMUTE)
        return;

    if (ms == BEEPER_ERROR)
    {
        beeperLoopPlay(ERROR_DURATION, 3);
    }
    else if (ms == BEEPER_INFO)
    {
        beeperLoopPlay(INFO_DURATION, 1);
    }
    else if (ms == BEEPER_WARNING)
    {
        beeperLoopPlay(WARN_DURATION, 2);
    }
    else
    {
        trigger(ms);
    }
}
/**
 * @brief : 让蜂鸣器循环响，按照50%的占空比
 * @param {uint8_t} freq 循环的周期
 * @param {uint8_t} time 循环的次数,为1时只响一下
 * @return {*}
 */
void beeperLoopPlay(uint8_t ms, uint8_t time)
{
    if (State != BEEPER_UNMUTE)
        return;
    repeatTimes = time;
    if (time == 1)
    {
        trigger(ms);
    }
    else
    {
        repeatBeep(ms);
    }
}
#endif // !1
